package com.geek.novel.utils

import android.content.Context
import android.content.SharedPreferences
import android.util.Base64
import com.geek.novel.bo.AppContext
import java.io.*
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method

/**
 * Created by Administrator on 2017/5/22.
 */

object SPUtil {

    const val usrInfo = "usrInfo"// 用户状态
    const val sysInfo = "sysInfo"// 用户状态
	
    const val SP_UPDATE_HTTP_SERVICE_IP = "SP_UPDATE_HTTP_SERVICE_IP"//IP数据存储
    const val updateServiceIp = "updateServiceIp"//IP数据存储(key)


	const val SP_SYSTEM_SETUP = "SP_SYSTEM_SETUP"//书籍的系统配置
	const val book_text_size = "book_text_size"// 字体大小配置
    const val book_line_height = "book_line_height"// 字体行间距大小配置
    const val book_typeface = "book_typeface"// 字体文件
    const val book_pull_page_next = "book_pull_page_next"// 全屏点击翻页
    const val book_voice_page = "book_voice_page"// 音量键点击翻页
    const val book_lock_screen_never = "book_lock_screen_never"// 是否永不锁屏
    const val book_auto_turn_page = "book_auto_turn_page"// 自动翻页
    const val book_auto_turn_page_time = "book_auto_turn_page_time"// 自动翻页时长
    const val book_system_bright = "book_system_bright"// 是否跟随系统亮度
    const val book_system_bright_percent = "book_system_bright_percent"// 当前亮度设置百分比
    const val book_index_sort_desc = "book_index_sort_desc"// 章节排序是否倒序

    const val app_current_theme = "app_current_theme"// 当前主题

    /**用户退出时停留的fragment*/
    const val main_fragment_user_select = "main_fragment_user_select"

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     */
    fun put(key: String, `object`: Any, fileName: String) {
        val sp = AppContext.getContext().getSharedPreferences(fileName, Context.MODE_PRIVATE)
        val editor = sp.edit()
		when (`object`) {
			is String -> editor.putString(key, `object`)
			is Int -> editor.putInt(key, `object`)
			is Boolean -> editor.putBoolean(key, `object`)
			is Float -> editor.putFloat(key, `object`)
			is Long -> editor.putLong(key, `object`)
			else -> editor.putString(key, `object`.toString())
		}
    
        SharedPreferencesCompat.apply(editor)

    }


    operator fun get(key: String, fileName: String): Any? {
        return get(key, "", fileName)
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对于的方法获取值
     */
    operator fun get(key: String, defaultObject: Any, fileName: String): Any? {
        val sp = AppContext.getContext().getSharedPreferences(fileName,
                Context.MODE_PRIVATE)
		return when (defaultObject) {
			is String -> sp.getString(key, defaultObject)
			is Int -> sp.getInt(key, defaultObject)
			is Boolean -> sp.getBoolean(key, defaultObject)
			is Float -> sp.getFloat(key, defaultObject)
			is Long -> sp.getLong(key, defaultObject)
			else -> null
		}
	
	}

    /**
     * 移除某个key值已经对应的值
     */
    fun remove(key: String, fileName: String) {
        val sp = AppContext.getContext().getSharedPreferences(fileName, Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.remove(key)
        SharedPreferencesCompat.apply(editor)
    }

    /**
     * 清除所有数据
     */
    fun clear(context: Context, fileName: String) {
        val sp = context.getSharedPreferences(fileName,
                Context.MODE_PRIVATE)
        val editor = sp.edit()
        editor.clear()
        SharedPreferencesCompat.apply(editor)
    }

    /**
     * 查询某个key是否已经存在
     */
    fun contains(context: Context, key: String, fileName: String): Boolean {
        val sp = context.getSharedPreferences(fileName,
                Context.MODE_PRIVATE)
        return sp.contains(key)
    }

    /**
     * 返回所有的键值对
     */
    fun getAll(context: Context, fileName: String): Map<String, *> {
        val sp = context.getSharedPreferences(fileName,
                Context.MODE_PRIVATE)
        return sp.all
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     */
    private object SharedPreferencesCompat {
        private val sApplyMethod = findApplyMethod()

        /**
         * 反射查找apply的方法
         */
        private fun findApplyMethod(): Method? {
            try {
                val clz = SharedPreferences.Editor::class.java
                return clz.getMethod("apply")
            } catch (e: NoSuchMethodException) {
            }

            return null
        }

        /**
         * 如果找到则使用apply执行，否则使用commit
         */
        fun apply(editor: SharedPreferences.Editor) {
            try {
                if (sApplyMethod != null) {
                    sApplyMethod.invoke(editor)
                    return
                }
            } catch (e: IllegalArgumentException) {
            } catch (e: IllegalAccessException) {
            } catch (e: InvocationTargetException) {
            }

            editor.commit()
        }
    }

    /**
     * writeObject 方法负责写入特定类的对象的状态，以便相应的 readObject 方法可以还原它
     * 最后，用Base64.encode将字节文件转换成Base64编码保存在String中

     * @param object
     * *            待加密的转换为String的对象
     * *
     * @return String 加密后的String
     */
    private fun object2String(`object`: Any): String? {

        val byteArrayOutputStream = ByteArrayOutputStream()
        var objectOutputStream: ObjectOutputStream? = null
        try {
            objectOutputStream = ObjectOutputStream(byteArrayOutputStream)
            objectOutputStream.writeObject(`object`)
	
			return String(Base64.encode(
					byteArrayOutputStream.toByteArray(), Base64.DEFAULT))
        } catch (e: IOException) {
            e.printStackTrace()
            return null
        } finally {
            try {
                byteArrayOutputStream.close()
                objectOutputStream!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }
    }

    /**
     * 使用Base64解密String，返回Object对象

     * @param objectString
     * *            待解密的String
     * *
     * @return object 解密后的object
     */
    private fun string2Object(objectString: String): Any? {
        val mobileBytes = Base64.decode(objectString.toByteArray(),
                Base64.DEFAULT)
        val byteArrayInputStream = ByteArrayInputStream(
                mobileBytes)
        var objectInputStream: ObjectInputStream? = null
        try {
            objectInputStream = ObjectInputStream(byteArrayInputStream)
    
            return objectInputStream.readObject()
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        } finally {
            try {
                byteArrayInputStream.close()
                objectInputStream!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }

        }

    }

    /**
     * 使用SharedPreference保存对象

     * @param fileKey
     * *            储存文件的key
     * *
     * @param key
     * *            储存对象的key
     * *
     * @param saveObject
     * *            储存的对象
     */
    /*fun set(key: String, saveObject: Any,
             fileName: String) {
        val sharedPreferences = AppContext.getContext()
                .getSharedPreferences(fileName, Context.MODE_PRIVATE)
        val editor = sharedPreferences.edit()
        val string = object2String(saveObject)
        editor.putString(key, string)
        SharedPreferencesCompat.apply(editor)
    }*/

    /**
     * 获取SharedPreference保存的对象

     * @param fileKey
     * *            储存文件的key
     * *
     * @param key
     * *            储存对象的key
     * *
     * @return object 返回根据key得到的对象
     */
    /*operator fun get(key: String, fileName: String): Any? {
        val sharedPreferences = AppContext.getContext()
                .getSharedPreferences(fileName, Context.MODE_PRIVATE)
        val string = sharedPreferences.getString(key, null)
        return if (string != null) {
            string2Object(string)
        } else {
            null
        }
    }*/

}